#pragma once
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include "Connection.hpp"
#include "HandlerEvent.hpp"
#include "Commom.hpp"
// 用来处理连接的
class Accept
{
public:
    Accept() {}
    ~Accept() {}

    void AcceptConnection(ConnectionPtr conn)
    {
        errno = 0;
        // 循环获取
        while (true)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            // 由于是ET模式下，所以必须一直获取!! 必须先把listensock设置为非阻塞
            int sockfd = accept(conn->GetSockfd(), (struct sockaddr *)&peer, &len);
            if (sockfd > 0)
            {
                // 设置为非阻塞
                SetNonBlock(sockfd);
                ILOG("获取一个新连接%d", sockfd);
                // 获取连接之后呢？？添加事件到conn和epoll
                // 创建回调函数
                auto recver = std::bind(&HandlerEvent::recver, std::placeholders::_1);
                auto sender = std::bind(&HandlerEvent::sender, std::placeholders::_1);
                auto excepter = std::bind(&HandlerEvent::excepter, std::placeholders::_1);
                ConnectionPtr normalconn = ConnectionFactory::BuildNormalConnn(sockfd, EPOLLIN | EPOLLET, recver, sender, excepter, conn->_R);
                // 添加到epoll
                conn->_R->AddConnection(normalconn);
            }
            else
            {
                // 读完了
                if (errno == EAGAIN)
                    break;
                if (errno == EINTR)
                    continue;
                else
                {
                    // 异常事件
                    ELOG("获取新连接出现失败! %d:%s", errno, strerror(errno));
                    break;
                }
            }
        }
    }
};